package com.douyin.controller;

import com.douyin.common.Result;
import com.douyin.service.MonitoringService;
import com.douyin.service.StatisticsService;
import com.douyin.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/admin/monitoring")
@RequiredArgsConstructor
public class MonitoringController {
    
    private final MonitoringService monitoringService;
    private final StatisticsService statisticsService;
    private final JwtUtil jwtUtil;
    
    /**
     * 获取实时监控数据
     */
    @GetMapping("/realtime")
    public Result<?> getRealtimeMetrics(HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            Map<String, Object> metrics = monitoringService.getRealtimeMetrics();
            return Result.success(metrics);
        } catch (Exception e) {
            log.error("获取实时监控数据失败", e);
            return Result.error("获取实时监控数据失败");
        }
    }
    
    /**
     * 获取系统健康状态
     */
    @GetMapping("/health")
    public Result<?> getSystemHealth(HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            Map<String, Object> health = monitoringService.performHealthCheck();
            return Result.success(health);
        } catch (Exception e) {
            log.error("获取系统健康状态失败", e);
            return Result.error("获取系统健康状态失败");
        }
    }
    
    /**
     * 获取告警信息
     */
    @GetMapping("/alerts")
    public Result<?> getAlerts(HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            List<Map<String, Object>> alerts = monitoringService.getActiveAlerts();
            return Result.success(alerts);
        } catch (Exception e) {
            log.error("获取告警信息失败", e);
            return Result.error("获取告警信息失败");
        }
    }
    
    /**
     * 获取用户行为分析报告
     */
    @GetMapping("/user-behavior")
    public Result<?> getUserBehaviorReport(@RequestParam(required = false) String startTime,
                                          @RequestParam(required = false) String endTime,
                                          HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            LocalDateTime start = parseDateTime(startTime, LocalDateTime.now().minusDays(7));
            LocalDateTime end = parseDateTime(endTime, LocalDateTime.now());
            
            Map<String, Object> report = monitoringService.getUserBehaviorReport(start, end);
            return Result.success(report);
        } catch (Exception e) {
            log.error("获取用户行为分析报告失败", e);
            return Result.error("获取用户行为分析报告失败");
        }
    }
    
    /**
     * 获取性能监控数据
     */
    @GetMapping("/performance")
    public Result<?> getPerformanceMetrics(@RequestParam(required = false) String period,
                                         HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            String timePeriod = period != null ? period : "24h";
            LocalDateTime startTime = getStartTimeByPeriod(timePeriod);
            LocalDateTime endTime = LocalDateTime.now();
            
            Map<String, Object> performance = new HashMap<>();
            
            // 获取基本性能指标
            Map<String, Object> basicMetrics = monitoringService.getRealtimeMetrics();
            performance.put("current", basicMetrics);
            
            // 获取详细统计
            Map<String, Object> detailedStats = statisticsService.getComprehensiveReport(startTime, endTime);
            performance.put("detailed", detailedStats);
            
            return Result.success(performance);
        } catch (Exception e) {
            log.error("获取性能监控数据失败", e);
            return Result.error("获取性能监控数据失败");
        }
    }
    
    /**
     * 获取错误分析报告
     */
    @GetMapping("/errors")
    public Result<?> getErrorAnalysis(@RequestParam(required = false) String startTime,
                                     @RequestParam(required = false) String endTime,
                                     @RequestParam(defaultValue = "10") int limit,
                                     HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            LocalDateTime start = parseDateTime(startTime, LocalDateTime.now().minusDays(7));
            LocalDateTime end = parseDateTime(endTime, LocalDateTime.now());
            
            Map<String, Object> errorAnalysis = new HashMap<>();
            
            // 获取实时错误分布
            Map<String, Object> realtimeMetrics = monitoringService.getRealtimeMetrics();
            errorAnalysis.put("errorDistribution", realtimeMetrics.get("errorDistribution"));
            errorAnalysis.put("errorRate", realtimeMetrics.get("successRate"));
            
            // 获取热门错误
            // 这里可以从StatisticsService获取更详细的错误分析
            errorAnalysis.put("topErrors", new ArrayList<>());
            errorAnalysis.put("errorTrends", new ArrayList<>());
            
            return Result.success(errorAnalysis);
        } catch (Exception e) {
            log.error("获取错误分析报告失败", e);
            return Result.error("获取错误分析报告失败");
        }
    }
    
    /**
     * 获取地理位置统计
     */
    @GetMapping("/geography")
    public Result<?> getGeographyStats(@RequestParam(required = false) String startTime,
                                      @RequestParam(required = false) String endTime,
                                      HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            LocalDateTime start = parseDateTime(startTime, LocalDateTime.now().minusDays(7));
            LocalDateTime end = parseDateTime(endTime, LocalDateTime.now());
            
            Map<String, Object> geoStats = monitoringService.getUserBehaviorReport(start, end);
            Map<String, Object> geographicalData = (Map<String, Object>) geoStats.get("geographicalDistribution");
            
            return Result.success(geographicalData);
        } catch (Exception e) {
            log.error("获取地理位置统计失败", e);
            return Result.error("获取地理位置统计失败");
        }
    }
    
    /**
     * 获取监控概览
     */
    @GetMapping("/overview")
    public Result<?> getMonitoringOverview(HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            Map<String, Object> overview = new HashMap<>();
            
            // 实时指标
            Map<String, Object> realtime = monitoringService.getRealtimeMetrics();
            overview.put("realtime", realtime);
            
            // 系统健康状态
            Map<String, Object> health = monitoringService.performHealthCheck();
            overview.put("health", health);
            
            // 活跃告警
            List<Map<String, Object>> alerts = monitoringService.getActiveAlerts();
            overview.put("alerts", alerts);
            
            // 今日统计
            LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
            Map<String, Object> todayStats = statisticsService.getComprehensiveReport(today, LocalDateTime.now());
            overview.put("todayStats", todayStats);
            
            return Result.success(overview);
        } catch (Exception e) {
            log.error("获取监控概览失败", e);
            return Result.error("获取监控概览失败");
        }
    }
    
    /**
     * 手动触发系统清理
     */
    @PostMapping("/cleanup")
    public Result<?> triggerCleanup(@RequestBody Map<String, Object> request,
                                   HttpServletRequest httpRequest) {
        if (!validateAdminToken(httpRequest)) {
            return Result.unauthorized();
        }
        
        try {
            String type = (String) request.get("type");
            Integer days = (Integer) request.get("days");
            
            if (type == null) {
                return Result.error("清理类型不能为空");
            }
            
            if (days == null || days < 1) {
                return Result.error("请指定有效的清理天数");
            }
            
            String message;
            switch (type.toLowerCase()) {
                case "logs":
                    // 清理日志数据
                    message = "日志清理完成";
                    break;
                case "records":
                    // 清理解析记录
                    message = "解析记录清理完成";
                    break;
                case "statistics":
                    // 清理统计数据
                    message = "统计数据清理完成";
                    break;
                default:
                    return Result.error("不支持的清理类型");
            }
            
            log.info("管理员触发{}清理，保留{}天内数据", type, days);
            return Result.success(message);
            
        } catch (Exception e) {
            log.error("系统清理失败", e);
            return Result.error("系统清理失败");
        }
    }
    
    /**
     * 重置监控计数器
     */
    @PostMapping("/reset-counters")
    public Result<?> resetCounters(HttpServletRequest request) {
        if (!validateAdminToken(request)) {
            return Result.unauthorized();
        }
        
        try {
            // 这里应该调用MonitoringService的重置方法
            log.info("管理员重置监控计数器");
            return Result.success("监控计数器已重置");
        } catch (Exception e) {
            log.error("重置监控计数器失败", e);
            return Result.error("重置监控计数器失败");
        }
    }
    
    // 私有辅助方法
    
    private boolean validateAdminToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            return false;
        }
        
        token = token.substring(7);
        if (!jwtUtil.validateToken(token)) {
            return false;
        }
        
        String userType = jwtUtil.getUserTypeFromToken(token);
        return "admin".equals(userType);
    }
    
    private LocalDateTime parseDateTime(String dateTimeStr, LocalDateTime defaultValue) {
        if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
            return defaultValue;
        }
        
        try {
            return LocalDateTime.parse(dateTimeStr);
        } catch (DateTimeParseException e) {
            log.warn("日期时间解析失败: {}", dateTimeStr);
            return defaultValue;
        }
    }
    
    private LocalDateTime getStartTimeByPeriod(String period) {
        LocalDateTime now = LocalDateTime.now();
        
        switch (period.toLowerCase()) {
            case "1h":
                return now.minusHours(1);
            case "6h":
                return now.minusHours(6);
            case "24h":
                return now.minusDays(1);
            case "7d":
                return now.minusDays(7);
            case "30d":
                return now.minusDays(30);
            default:
                return now.minusDays(1);
        }
    }
}